iT邦幫忙

2023 iThome 鐵人賽

DAY 7
0
Software Development

30天快速打造Python資料結構&演算法邏輯刷爆LeetCode系列 第 7

DAY 7 「合併排序 (Merge Sort)」簡簡單單教會你Python程式碼撰寫~

  • 分享至 

  • xImage
  •  

下個分治法的排序繼續~合併拆解思維邏輯~

進入下一個排序演算法~~
/images/emoticon/emoticon07.gif白話來說分割+合併,每次都將數列平均地分為兩半相等的子數列,直到每個子數列中只剩下一個元素為止,最後將2個已排序的子數列合併成一個有序的數列,並保持整個數列的有序性~~

  • 平均時間複雜度/最壞(全部大小相反)情況時間複雜度皆為O(n log n)
  • 穩定排序(相同元素的相對位置每次排序完全一致)
  • 分治法(Divide and Conquer)

假設我們有一個數列 [38, 27, 43, 3, 9, 82, 10]
Step1: 分割:分割成兩個部分,繼續分割到只剩下一個元素
=> 左半部分: [38, 27, 43]
=> 右半部分: [3, 9, 82, 10]
=================
=> 左半部分: [38]
=> 右半部分: [27, 43]
=================
...
Step2: 合併:接下來,我們開始將這些單個元素合併起來,同時保持它們的排序
=> 首先,將 [27] 和 [43] 合併,得到 [27, 43]。
=> 然後,將 [38] 和 [27, 43] 合併,得到 [27, 38, 43]。
=================
...
=================
最終,將 [3, 9, 10, 82] 合併成 [3, 9, 10, 82]。
=================
最後一步,將左半部分 [27, 38, 43] 和右半部分 [3, 9, 10, 82] 合併成最終排序好的數列 [3, 9, 10, 27, 38, 43, 82]。
=================

# Step1: 分割:分割成兩個部分,繼續分割到只剩下一個元素
def merge_sort(arr):
    if len(arr) <= 1:
        return arr

    # 將數列分成兩半
    mid = len(arr) // 2
    left = arr[:mid]
    right = arr[mid:]

    # 遞迴地對左右兩半進行排序
    left = merge_sort(left)
    right = merge_sort(right)

    # 將已排序的兩半合併
    return merge(left, right)

Step2: 合併:接下來,我們開始將這些單個元素合併起來,同時保持它們的排序
def merge(left, right):
    result = []
    i = j = 0

    while i < len(left) and j < len(right):
        if left[i] < right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1

    result.extend(left[i:])
    result.extend(right[j:])

    return result


arr = [38, 27, 43, 3, 9, 82, 10]
sorted_arr = merge_sort(arr)
print(sorted_arr)

上一篇
DAY 6 「快速排序(Quick Sort)」Python分治法(Divide and Conquer)演算法的最開端~
下一篇
DAY 8 「冒泡排序 (Bubble Sort)」最快理解的排序用Python程式碼撰寫~
系列文
30天快速打造Python資料結構&演算法邏輯刷爆LeetCode30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言